package com.spring.sunflower.http;

import com.blankj.utilcode.util.DeviceUtils;
import com.blankj.utilcode.util.SPUtils;
import com.google.gson.Gson;
import com.spring.sunflower.ResponseConverterFactory;
import com.spring.sunflower.base.BaseApplication;
import com.spring.sunflower.constant.Constant;
import com.spring.sunflower.util.AppUtils;
import com.spring.sunflower.util.ChannelInfoUtils;
import com.spring.sunflower.util.LogUtils;

import java.io.IOException;
import java.net.Proxy;
import java.net.ProxySelector;
import java.net.SocketAddress;
import java.net.URI;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;

import okhttp3.FormBody;
import okhttp3.HttpUrl;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
import okio.Buffer;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

/**
 * Created by <a href="http://blog.csdn.net/student9128">Kevin</a> on 2017/6/11.
 * <p>Blog:http://blog.csdn.net/student9128.
 * <p>
 * <h3>Description:</h3>
 * <p>
 * <p>
 */


public class AppRetrofit {
    public static String BASE_URL = "http://47.115.39.13:8088/";
    private static int CONNET_TIME_OUT = 20;
    private static int READ_TIME_OUT = 120;
    private Retrofit retrofit;
    private static AppRetrofit appRetrofit;
    private static AppRetrofit dynamicAppRetrofit;//动态改变BASEURL
    private static CacheInterceptor cacheInterceptor = new CacheInterceptor();//缓存拦截器

    public AppRetrofit() {
        retrofit = new Retrofit.Builder()
                .client(initBuilder().build())
//                .addConverterFactory(GsonConverterFactory.create())
                .addConverterFactory(ResponseConverterFactory.create(new Gson()))
                .addCallAdapterFactory(RxJava3CallAdapterFactory.create())
                .baseUrl(Constant.BASE_URL)
                .build();
    }

    public <T> T create(Class<T> service) {

        return retrofit.create(service);
    }

    public AppRetrofit(String baseUrl) {
        retrofit = new Retrofit.Builder()
                .client(initBaseBuilder().build())
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava3CallAdapterFactory.create())
                .baseUrl(baseUrl)
                .build();
    }

    public AppRetrofit(int connectTimeOut) {
        CONNET_TIME_OUT = connectTimeOut;
        retrofit = new Retrofit.Builder()
                .client(initBuilder().build())
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava3CallAdapterFactory.create())
                .build();
    }

    private OkHttpClient.Builder initBuilder() {
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        builder.sslSocketFactory(SSLSocketFactoryUtils.createSSLSocketFactory(), SSLSocketFactoryUtils.createTrustAllManager())
                .hostnameVerifier(new SSLSocketFactoryUtils.TrustAllHostnameVerifier());
        builder.proxy(Proxy.NO_PROXY);
        builder.proxySelector(new ProxySelector() {
            @Override
            public List<Proxy> select(URI uri) {
                return Collections.singletonList(Proxy.NO_PROXY);
            }

            @Override
            public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {

            }
        });
//        builder.sslSocketFactory(TrustManager.getUnsafeOkHttpClient())
//                .hostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
        builder.addInterceptor(new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                Request request = chain.request();
                HttpUrl oldHttpUrl = request.url();
                Request.Builder requestBuilder = request.newBuilder();
                requestBuilder.addHeader("appId", AppUtils.getPackageName(BaseApplication.getContext()));
                requestBuilder.addHeader("osType", "1"); //设备类型（1 android 2 ios）
                requestBuilder.addHeader("macId", AppUtils.getMac(BaseApplication.getContext())); //设备唯一标识符
                requestBuilder.addHeader("version", String.valueOf(AppUtils.getVersionCode(BaseApplication.getContext())));
                requestBuilder.addHeader("Content-Type", "application/json");
                String token = SPUtils.getInstance().getString(Constant.KEY_TOKEN, "");
                requestBuilder.addHeader("token", token);
                requestBuilder.addHeader("market", ChannelInfoUtils.getChannel(BaseApplication.getContext()));
                requestBuilder.addHeader("MID", SPUtils.getInstance().getString(Constant.KEY_USERID, ""));
                requestBuilder.addHeader("deviceId", DeviceUtils.getUniqueDeviceId());
                requestBuilder.addHeader("User_Agent", android.os.Build.MODEL);
                requestBuilder.addHeader("isEncrypt", "yes");
                LogUtils.INSTANCE.logD("Apptrofit", "appid=" + AppUtils.getPackageName(BaseApplication.getContext()) + "," +
                        "macID=" + AppUtils.getMac(BaseApplication.getContext()) + ",token=" + token + "");
//                List<String> headerValues = request.headers("url_name");
//                if (headerValues != null && headerValues.size() > 0) {
//                    requestBuilder.removeHeader("url_name");
//                    String headerValue = headerValues.get(0);
//                    HttpUrl newBaseUrl = oldHttpUrl;
//                    HttpUrl newFullUrl = oldHttpUrl.newBuilder()
//                            .scheme(newBaseUrl.scheme())
//                            .host(newBaseUrl.host())
//                            .port(newBaseUrl.port())
//                            .build();
//                    return chain.proceed(requestBuilder.url(newFullUrl).build());
//                } else {
//                    return chain.proceed(request);
//                }
                return chain.proceed(requestBuilder.build());
            }
        });
        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        builder.addInterceptor(interceptor);
        builder.retryOnConnectionFailure(true);//连接失败后重试
        builder.connectTimeout(20, TimeUnit.SECONDS);
        builder.readTimeout(60, TimeUnit.SECONDS);
        return builder;
    }

    private OkHttpClient.Builder initBaseBuilder() {
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        builder.sslSocketFactory(SSLSocketFactoryUtils.createSSLSocketFactory(), SSLSocketFactoryUtils.createTrustAllManager())
                .hostnameVerifier(new SSLSocketFactoryUtils.TrustAllHostnameVerifier());
//        builder.sslSocketFactory(TrustManager.getUnsafeOkHttpClient())
//                .hostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        interceptor.setLevel(HttpLoggingInterceptor.Level.HEADERS);
        builder.addInterceptor(interceptor);
//        builder.addInterceptor(new Interceptor() {
//            @Override
//            public Response intercept(Chain chain) throws IOException {
//
//                Request.Builder builder = chain.request().newBuilder();
////                    builder.addHeader("Cookie", getCommonParameter());
//                builder.addHeader("osType", "1"); //设备类型（1 android 2 ios）
//                builder.addHeader("macId", SystemUtils.getMac(BaseApplication.getContext())); //设备唯一标识符
//                builder.addHeader("version", "1.0.0");
//                builder.addHeader("Content-Type", "application/json");
//                return chain.proceed(builder.build());
//            }
//        });
        builder.retryOnConnectionFailure(true);//连接失败后重试
        builder.connectTimeout(20, TimeUnit.SECONDS);
        builder.readTimeout(60, TimeUnit.SECONDS);
        return builder;
    }

    public static AppRetrofit getInstance() {
        if (appRetrofit == null) {
            synchronized (AppRetrofit.class) {
                if (appRetrofit == null) {
                    appRetrofit = new AppRetrofit();
                }
            }
        }
        return appRetrofit;
    }

    public static AppRetrofit getInstance(String baseUrl) {
        if (appRetrofit == null) {
            synchronized (AppRetrofit.class) {
                appRetrofit = new AppRetrofit(baseUrl);
            }
        }
        return appRetrofit;
    }

    public static void destroy() {
        if (appRetrofit != null) {
            appRetrofit = null;
        }
    }

    public HttpInterface getHttpService() {
        return getInstance().create(HttpInterface.class);
    }

    public HttpInterface getHttpService(String baseUrl) {
        return getInstance(baseUrl).create(HttpInterface.class);
    }


    class HttpBaseParamsLoggingInterceptor implements Interceptor {

        @Override
        public Response intercept(Chain chain) throws IOException {
            Request request = chain.request();
            Request.Builder requestBuilder = request.newBuilder();
            RequestBody formBody = new FormBody.Builder()
                    .add("channel", "wdj")
                    .add("version", "4.0.2")
                    .add("uuid", "ffffffff-a90e-706a-63f7-ccf973aae5ee")
                    .add("platform", "android")
                    .build();
            String postBodyString = bodyToString(request.body());
            postBodyString += ((postBodyString.length() > 0) ? "&" : "") + bodyToString(formBody);
            request = requestBuilder
                    .post(RequestBody.create(MediaType.parse("application/x-www-form-urlencoded;charset=UTF-8"),
                            postBodyString))
                    .build();
            return chain.proceed(request);
        }

        public String bodyToString(final RequestBody request) {
            try {
                final RequestBody copy = request;
                final Buffer buffer = new Buffer();
                if (copy != null)
                    copy.writeTo(buffer);
                else
                    return "";
                return buffer.readUtf8();
            } catch (final IOException e) {
                return "did not work";
            }
        }
    }
}
